"""
Translator.py -- loading language information from Translations.xml.

Contains class which loads the appropriate method bodies an comments
according to the wanted language. Is used by the Interpretor class
from Interpretor.py.
"""

##@package Translator
# Contains class which loads the appropriate method bodies an comments
# according to the wanted language. Is used by the Interpretor class
# from Interpretor.py.
#
# @author Johan "Solo" Luisier
# @date November 2011

from xml.dom import minidom, Node
from XmlCppClassGenerator.BaseReader import _BaseReader
import codecs

## Class loading the appropriate translation.
# The appropriate method comments, messages and simple strings
# according to the wanted language. The information is loaded from
# XmlCppClassGeneratorInfo/Translations.xml.
#
# Inherits from _BaseReader since the basic functionality is provided
# by this class.
#
# @author Johan "Solo" Luisier
# @date November 2011
class Translator( _BaseReader ) :
    ## Constructor
    # Initialises the class fields, does the parsing and loads the
    # needed information from Translation.xml.
    #
    # Can stop the execution if the file has an incorrect syntax or
    # missing data. If the wanted language does not exist in the xml
    # translation file, the default value (en=english) is used.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] lang name of the wanted language (english is the
    # default).
    def __init__( self, lang='en' ) :
        from XmlCppClassGenerator import fullPath
        _BaseReader.__init__( self, fullPath() + 'Translations.xml' )
        if ( not self.checkRootNode( 'translations' ) ) :
            exit( 1 )
        self.__XmlWantedNode = None
        self.__AvailableLanguages = []
        found = self.lookForLanguage( lang )
        if ( not found ) :
            message = "Could not retrieve the wanted language '" + lang + "' "
            message += "the default language will be used instead."
            self.warning( message )
            found = self.lookForLanguage( 'en' )
        if ( not found ) :
            message = "Neither the wanted language '" + lang + "'",
            message += "nor the default one" + 'en'
            message += "could not be retrieved"
            self.fatal( message )
            exit( 1 )
        self.__ConsideredComments = [ 'stdGetter',
                                      'stdSetter',
                                      'ptrGetter',
                                      'ptrSetter' ]
        self.__ConsideredStrings = [ 'constructor',
                                     'destructor',
                                     'getter',
                                     'setter',
                                     'method',
                                     'member' ]
        self.__ConsideredMessages = [ 'rootElementError',
                                      'ioError',
                                      'moveInfo',
                                      'addItem',
                                      'genMethod',
                                      'alreadyPresent',
                                      'objExist',
                                      'objIsFile',
                                      'processing',
                                      'nooutput',
                                      'validationError' ]
        self.__InformationComments = {}
        self.__InformationStrings = {}
        self.__InformationMessages = {}
        listOfNodes = [ self.__XmlWantedNode.getElementsByTagName( 'comments' )[0],
                        self.__XmlWantedNode.getElementsByTagName( 'strings' )[0],
                        self.__XmlWantedNode.getElementsByTagName( 'prgmMessages' )[0] ]
        listOfRefs = [ self.__ConsideredComments,
                       self.__ConsideredStrings,
                       self.__ConsideredMessages ]
        listOfInfo = [ self.__InformationComments,
                       self.__InformationStrings,
                       self.__InformationMessages ]
                        
        if ( not self._loadInformation( listOfNodes, listOfRefs, listOfInfo )  ):
            print "Could not get all the needed information from the xml",
            print "file, must abort."
            exit( 1 )
    ## Looks for the given translation and saves the node which
    # contains the wanted information.
    #
    # @param[in] self reference on calling instance.
    # @param[in] language name of the wanted language
    #
    # @return \e True if the wanted language was found, \e False if
    # not.
    def lookForLanguage( self, language ) :
        for child in self._getXmlDomRoot().childNodes :
            if ( child.nodeName == 'translation' ) :
                for ( name, value ) in child.attributes.items() :
                    if ( name == 'language' ) :
                        langArray = {}
                        langArray[ 'code' ] = value
                        for node in child.childNodes :
                            if ( node.nodeName == 'langName' ) :
                                langArray[ 'name' ] = node.firstChild.nodeValue.strip()
                            elif ( node.nodeName == 'nativeName' ) :
                                langArray[ 'native' ] = node.firstChild.nodeValue.strip()
                        self.__AvailableLanguages.append( langArray )
                        if ( value == language ) :
                            self.__XmlWantedNode = child
        return ( self.__XmlWantedNode != None )
    ## Allows to get the list of available languages.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the value of __AvailableLanguages.
    def getAvailableLanguages( self ) :
        return self.__AvailableLanguages
    ## Allows to access the wanted information about function comments
    # from the translator instance.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] key key of the wanted information.
    #
    # @return a tuple containing the wanted information and the number
    # of strings to be replaced with format().
    def getInformationComment( self, key ) :
        return self._getInformation( self.__InformationComments, key )
    ## Allows to access the wanted information about basic strings
    # from the translator instance.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] key key of the wanted information.
    #
    # @return a tuple containing the wanted information and the number
    # of strings to be replaced with format().
    def getInformationString( self, key ) :
        return self._getInformation( self.__InformationStrings, key )
    ## Allows to access the wanted information about prgm messages from
    # the translator instance.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] key key of the wanted information.
    #
    # @return a tuple containing the wanted information and the number
    # of strings to be replaced with format().
    def getInformationMessage( self, key ) :
        return self._getInformation( self.__InformationMessages, key )
